


#ifdef _WIN32
// 防火墙功能仅支持 Linux 系统
#define firewall_init() 0
#define firewall_uninit() ((void)0)
#else

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

// 防火墙规则结构
typedef struct {
    int id;
    char protocol[16];    // tcp/udp/icmp/all
    char port[64];        // 端口或端口范围
    char source_ip[128];  // 源IP地址（可选）
    char action[16];      // ACCEPT/DROP/REJECT
    char comment[256];    // 备注
    int enabled;          // 是否启用
} FirewallRule;

// 防火墙配置路径
#define FIREWALL_CONFIG_PATH "../data/options/firewall.json"

// 执行shell命令并获取输出
static char* exec_cmd(const char* cmd) {
    FILE* fp = popen(cmd, "r");
    if (!fp) return NULL;
    
    char* result = (char*)malloc(65536);
    if (!result) {
        pclose(fp);
        return NULL;
    }
    
    size_t total = 0;
    char buffer[1024];
    while (fgets(buffer, sizeof(buffer), fp)) {
        size_t len = strlen(buffer);
        if (total + len < 65535) {
            memcpy(result + total, buffer, len);
            total += len;
        }
    }
    result[total] = '\0';
    
    pclose(fp);
    return result;
}

// 保存防火墙配置到JSON文件
static int firewall_save_config(struct mg_str rules_json) {
    char filepath[512];
    snprintf(filepath, sizeof(filepath), "%s", FIREWALL_CONFIG_PATH);
    
    FILE* fp = fopen(filepath, "w");
    if (!fp) {
        printf("无法保存防火墙配置文件: %s\n", filepath);
        return -1;
    }
    
    fwrite(rules_json.buf, 1, rules_json.len, fp);
    fclose(fp);
    
    printf("防火墙配置已保存\n");
    return 0;
}

// 从JSON文件加载防火墙配置
static char* firewall_load_config() {
    char filepath[512];
    snprintf(filepath, sizeof(filepath), "%s", FIREWALL_CONFIG_PATH);
    
    FILE* fp = fopen(filepath, "r");
    if ( !fp ) {
        printf("防火墙配置文件不存在: %s\n", filepath);
        return NULL;
    }
    
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    fseek(fp, 0, SEEK_SET);
    
    char* content = (char*)malloc(size + 1);
    if (!content) {
        fclose(fp);
        return NULL;
    }
    
    fread(content, 1, size, fp);
    content[size] = '\0';
    fclose(fp);
    
    return content;
}

// 应用单条防火墙规则到iptables
static int firewall_apply_rule(FirewallRule* rule) {
    if (!rule->enabled) return 0;
    
    char cmd[2048];
    char port_spec[128] = "";
    char source_spec[256] = "";
    char proto_spec[32] = "";
    
    // 构建协议参数
    if (strcmp(rule->protocol, "all") != 0) {
        snprintf(proto_spec, sizeof(proto_spec), "-p %s", rule->protocol);
    }
    
    // 构建端口参数
    if (rule->port[0] && strcmp(rule->protocol, "icmp") != 0) {
        snprintf(port_spec, sizeof(port_spec), "--dport %s", rule->port);
    }
    
    // 构建源IP参数
    if (rule->source_ip[0]) {
        snprintf(source_spec, sizeof(source_spec), "-s %s", rule->source_ip);
    }
    
    // 构建iptables命令
    snprintf(cmd, sizeof(cmd), 
        "iptables -A INPUT %s %s %s -j %s -m comment --comment \"xpanel_fw_%d\"",
        proto_spec, source_spec, port_spec, rule->action, rule->id);
    
    printf("执行防火墙规则: %s\n", cmd);
    int ret = system(cmd);
    
    return ret == 0 ? 0 : -1;
}

// 清除所有xpanel管理的防火墙规则
static int firewall_clear_rules() {
    char cmd[512];
    
    // 查找所有带有xpanel_fw标记的规则并删除
    char* output = exec_cmd("iptables -L INPUT --line-numbers -n | grep 'xpanel_fw_' | awk '{print $1}' | tac");
    if (output) {
        char* line = strtok(output, "\n");
        while (line) {
            int line_num = atoi(line);
            if (line_num > 0) {
                snprintf(cmd, sizeof(cmd), "iptables -D INPUT %d", line_num);
                system(cmd);
            }
            line = strtok(NULL, "\n");
        }
        free(output);
    }
    
    printf("已清除所有xpanel防火墙规则\n");
    return 0;
}

// 应用所有防火墙规则
static int firewall_apply_all_rules(const char* config_json) {
    if (!config_json) return -1;
    
    // 先清除现有规则
    firewall_clear_rules();
    
    // 简单解析JSON数组
    const char* p = config_json;
    while (*p && *p != '[') p++;
    if (*p != '[') return -1;
    p++;
    
    // 逐条解析规则
    while (*p) {
        // 跳过空白
        while (*p && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t')) p++;
        if (*p == ']') break;
        if (*p == ',') { p++; continue; }
        if (*p != '{') break;
        
        FirewallRule rule;
        memset(&rule, 0, sizeof(rule));
        rule.enabled = 1;
        
        // 解析对象
        p++;
        while (*p && *p != '}') {
            // 跳过空白和逗号
            while (*p && (*p == ' ' || *p == '\n' || *p == '\r' || *p == '\t' || *p == ',')) p++;
            if (*p != '"') break;
            
            // 读取键名
            p++;
            char key[64] = {0};
            int ki = 0;
            while (*p && *p != '"' && ki < 63) key[ki++] = *p++;
            if (*p == '"') p++;
            
            // 跳过冒号
            while (*p && (*p == ' ' || *p == ':')) p++;
            
            // 读取值
            char value[256] = {0};
            int vi = 0;
            if (*p == '"') {
                p++;
                while (*p && *p != '"' && vi < 255) value[vi++] = *p++;
                if (*p == '"') p++;
            } else {
                while (*p && *p != ',' && *p != '}' && vi < 255) {
                    if (*p != ' ' && *p != '\n' && *p != '\r' && *p != '\t') {
                        value[vi++] = *p;
                    }
                    p++;
                }
            }
            
            // 设置字段
            if (strcmp(key, "id") == 0) {
                rule.id = atoi(value);
            } else if (strcmp(key, "protocol") == 0) {
                strncpy(rule.protocol, value, sizeof(rule.protocol) - 1);
            } else if (strcmp(key, "port") == 0) {
                strncpy(rule.port, value, sizeof(rule.port) - 1);
            } else if (strcmp(key, "source_ip") == 0) {
                strncpy(rule.source_ip, value, sizeof(rule.source_ip) - 1);
            } else if (strcmp(key, "action") == 0) {
                strncpy(rule.action, value, sizeof(rule.action) - 1);
            } else if (strcmp(key, "enabled") == 0) {
                rule.enabled = atoi(value);
            }
        }
        
        if (*p == '}') p++;
        
        // 应用规则
        if (rule.id > 0 && rule.protocol[0] && rule.action[0]) {
            firewall_apply_rule(&rule);
        }
    }
    
    // 保存iptables规则
    system("iptables-save > /etc/iptables/rules.v4 2>/dev/null || true");
    
    return 0;
}

// 获取当前防火墙规则列表（从iptables读取）
static char* firewall_get_rules() {
    char* output = exec_cmd("iptables -L INPUT -n -v --line-numbers");
    if (!output) {
        return strdup("[]");
    }
    
    // 构建JSON数组
    char* json = (char*)malloc(65536);
    if (!json) {
        free(output);
        return strdup("[]");
    }
    
    strcpy(json, "[");
    
    char* line = strtok(output, "\n");
    int first = 1;
    
    // 跳过表头
    if (line) line = strtok(NULL, "\n");
    if (line) line = strtok(NULL, "\n");
    
    while (line) {
        // 解析iptables输出行
        if (strstr(line, "xpanel_fw_")) {
            char num[16], pkts[32], bytes[32], target[32], prot[16], opt[16];
            char in[16], out[16], source[64], destination[64];
            char extra[512];
            
            int n = sscanf(line, "%s %s %s %s %s %s %s %s %s %s %[^\n]",
                num, pkts, bytes, target, prot, opt, in, out, source, destination, extra);
            
            if (n >= 10) {
                // 提取规则ID
                char* comment_pos = strstr(line, "xpanel_fw_");
                int rule_id = 0;
                if (comment_pos) {
                    rule_id = atoi(comment_pos + 10);
                }
                
                // 提取端口
                char port[64] = "";
                char* dpt_pos = strstr(extra, "dpt:");
                if (dpt_pos) {
                    sscanf(dpt_pos + 4, "%s", port);
                }
                
                if (!first) strcat(json, ",");
                first = 0;
                
                char rule_json[1024];
                snprintf(rule_json, sizeof(rule_json),
                    "{\"id\":%d,\"protocol\":\"%s\",\"port\":\"%s\",\"source_ip\":\"%s\","
                    "\"action\":\"%s\",\"packets\":\"%s\",\"bytes\":\"%s\",\"enabled\":1}",
                    rule_id, prot, port, strcmp(source, "0.0.0.0/0") == 0 ? "" : source,
                    target, pkts, bytes);
                
                strcat(json, rule_json);
            }
        }
        
        line = strtok(NULL, "\n");
    }
    
    strcat(json, "]");
    free(output);
    
    return json;
}

// 初始化防火墙模块
static int firewall_init() {
    printf("初始化防火墙模块\n");
    
    // 检查是否是Linux系统
    #ifdef _WIN32
    printf("防火墙功能仅支持Linux系统\n");
    return -1;
    #endif
    
    // 检查iptables是否可用
    if (system("which iptables > /dev/null 2>&1") != 0) {
        printf("iptables未安装，防火墙功能不可用\n");
        return -1;
    }
    
    // 加载配置文件
    char* config = firewall_load_config();
    if (config) {
        printf("加载防火墙配置并应用规则\n");
        firewall_apply_all_rules(config);
        free(config);
    }
    
    return 0;
}

// 卸载防火墙模块
static void firewall_uninit() {
    printf("卸载防火墙模块\n");
}

#endif // _WIN32
